<?php defined('SYSPATH') OR die('No direct access allowed.');

class ManyToMany_Plugin extends WB_FormItem {
	
	var $primary_key;
	var $linking_table, $linking_field, $linking_linked;
	var $linked_table, $linked_primary_key, $linked_field;
	var $list_searched=FALSE, $available_list=array(), $joined_list=array(), $render_list=array();
	
	public function __construct($name='', $params=array())
	{
		parent::__construct($name, $params);
		
		$this->primary_key = $this->params['primary_key'];
		$this->linking_table = $this->params['linking']['table'];
		$this->linking_field = $this->params['linking']['field'];
		$this->linking_linked = $this->params['linking']['linked'];
		$this->linked_table = $this->params['linked']['table'];
		$this->linked_primary_key = $this->params['linked']['primary_key'];
		$this->linked_field = $this->params['linked']['field'];
		$this->linked_delete_col = 
				isset($this->params['linked']['delete_col']) ? 
					$this->params['linked']['delete_col'] : 
					FALSE;
		
		$this->form_columns = NULL;
		$this->table_columns = NULL;
		$this->db_columns = NULL;
		$this->table_columns[$this->name] = $this->db_table.'.'.$this->primary_key;
		$this->form_columns[$this->name] = $this->db_table.'.'.$this->primary_key;
		
		Event::add('wb_db.post_add_item', array($this, 'post_db'));
		Event::add('wb_db.post_edit_item', array($this, 'post_db'));
	}
	
	public function post_db()
	{
		$post = Kohana::instance()->input->post();
		$value = isset($post[$this->name]) ? $post[$this->name] : array();
		$id = Kohana::instance()->wb_db->get_last_id();
		
		$this->get_list();
		$selection = isset($this->joined_list[$id]) ? $this->joined_list[$id] : array();
		
		$ins = array();
		foreach ($value as $v) if ( ! in_array($v, $selection)) $ins[] = $v;
		
		$del = array();
		foreach ($selection as $k=>$v) if ( ! isset($value[$k])) $del[] = $k;
		
		if ( ! empty($ins) || ! empty($del))
		{
			$db = Kohana::instance()->db;
			$inserted = 0;
			$deleted = 0;
			foreach ($ins as $v)
			{
				$query = $db
					->set($this->linking_field, $id)
					->set($this->linking_linked, $v)
					->insert($this->linking_table);
				$inserted += $query->count();
			}
			foreach ($del as $v)
			{
				$query = $db
					->where($this->linking_field, $id)
					->where($this->linking_linked, $v)
					->delete($this->linking_table);
				$deleted += $query->count();
			}
			if ($inserted)
					Kohana::instance()
							->user_messages
									->add(Kohana::lang('manytomany_plugin.rows_inserted', $inserted), 'info');
			if ($deleted)
					Kohana::instance()
							->user_messages
									->add(Kohana::lang('manytomany_plugin.rows_deleted', $deleted), 'info');
		}
	}
	
	public function render_item()
	{
		$this->get_list();
		$value = is_array($this->value) ? $this->value[$this->primary_key] : $this->value;
		$selection = isset($this->joined_list[$value]) ? $this->joined_list[$value] : array();
		
		$str = $this->prefix;
		$str .= form::label($this->name, $this->label);
		$str .= form::dropdown(
				array(
					'name' => $this->name.'[]',
					'id' => $this->name,
					'multiple' => 'multiple',
					'size' => min(count($this->available_list), 20)
				),
				$this->available_list,
				$selection);
		$str .= $this->suffix;
		
		return $str;
	}
	
	public function render_cell()
	{
		$this->get_list();
		$value = is_array($this->value) ? $this->value[$this->primary_key] : $this->value;
		$joined = isset($this->render_list[$value]) ? $this->render_list[$value] : null;
		
		return empty($joined) ? '&nbsp;' : implode(', ', $joined);
	}
	
	public function get_list()
	{
		if ( ! $this->list_searched)
		{
			$this->list_searched = TRUE;
			
			
			$where = empty($linked_delete_col) ? '1' : $linked_delete_col.'=0';
			$query = Kohana::instance()->db
						->select($this->linked_primary_key.' AS key, '.$this->linked_field.' AS val')
						->from($this->linked_table)
						->where($where)
						->get();
			
			foreach ($query as $row) $this->available_list[$row->key] = $row->val;
						
			$query = Kohana::instance()->db
						->select($this->linking_field.' AS inner, '.$this->linking_linked.' AS outer')
						->from($this->linking_table)
						->get();
			
			foreach ($query->result_array(FALSE) as $row) 
			{
				$this->joined_list[$row['inner']][] =  $row['outer'];
				$this->render_list[$row['inner']][] = 
						isset($this->available_list[$row['outer']]) ?
							$this->available_list[$row['outer']] :
							$row['outer'];
			}
		}
	}
	
}

//End of ManyToMany_Plugin Library